package com.galeno.impl;

import com.galeno.dao.HistoryEventDao;
import com.galeno.pojo.CombineCondition;
import com.galeno.pojo.EventCondition;
import com.galeno.pojo.EventParam;
import com.galeno.pojo.LogBean;
import com.galeno.utils.ConnectionUtils;
import org.apache.flink.api.java.utils.ParameterTool;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author galeno
 * @Title:
 * @Description:
 * @date 2021/11/1320:04
 */
public class HistoryEventClickHouseDaoImpl implements HistoryEventDao {
    private Connection clickHouseConn;

//    /**
//     * 匹配用户事件
//     *
//     * @param logBean
//     * @param eventCountConditions
//     * @return
//     * @throws Exception
//     */
//    @Override
//    public boolean isMatchEventCount(LogBean logBean, List<EventParam> eventCountConditions) throws Exception {
//        if (eventCountConditions != null && eventCountConditions.size() > 0) {
//            for (EventParam eventCountCondition : eventCountConditions) {
//                //查询clickHouse
//                String sql = eventCountCondition.getSql();
//                Map<String, String> properties = eventCountCondition.getProperties();
//                for (String key : properties.keySet()) {
//                    String value = properties.get(key);
//                    sql += "and properties['" + key + "']='" + value + "' ";
//                }
//                PreparedStatement preparedStatement = clickHouseConn.prepareStatement(sql);
//                preparedStatement.setString(1, logBean.getDeviceId());
//                preparedStatement.setLong(2, eventCountCondition.getStartTime());
//                preparedStatement.setLong(3, eventCountCondition.getEndTime());
//                preparedStatement.setString(4, eventCountCondition.getEventId());
//
//                ResultSet resultSet = preparedStatement.executeQuery();
//
//                if (resultSet.next()) {
//                    long counts = resultSet.getLong(1);
//                    //将clickhouse中的与事先设置的阈值进行比对
//                    if (counts < eventCountCondition.getThreshold()) {
//                        return false;
//                    }
//                } else {
//                    return false;
//                }
//            }
//        }
//        return true;
//
//    }

    @Override
    public void close() throws Exception {
        if (clickHouseConn != null) {
            clickHouseConn.close();
        }
    }
//
//    /**
//     * 是否匹配上了指定的行为序列
//     *
//     * @param logBean
//     * @param eventSequenceCondition
//     * @return
//     * @throws Exception
//     */
//    @Override
//    public boolean isMatchEventSequence(LogBean logBean, List<EventParam> eventSequenceCondition) throws Exception {
//        if (eventSequenceCondition != null && eventSequenceCondition.size() > 1) {
//            EventParam eventParam = eventSequenceCondition.get(0);
//            String sql = eventParam.getSql();
//            StringBuffer buffer = new StringBuffer();
//            int index = 1;
//            for (EventParam param : eventSequenceCondition) {
//                String eventId = param.getEventId();
//                if (index > 1) {
//                    buffer.append("or");
//                }
//                buffer.append("(eventId='" + eventId + "'");
//                Map<String, String> properties = param.getProperties();
//                if (properties != null && properties.size() > 0) {
//                    Set<String> keySet = properties.keySet();
//                    for (String key : keySet) {
//                        String value = properties.get(key);
//                        buffer.append("and properties['" + key + "']='" + value + "'");
//                    }
//                }
//                buffer.append(")");
//                index++;
//            }
//            sql += " and (" + buffer.toString() + ") group by deviceId ";
//            System.out.println("======> " + sql);
//            //查询clickHouse
//            PreparedStatement preparedStatement = clickHouseConn.prepareStatement(sql);
//            preparedStatement.setString(1, logBean.getDeviceId());
//            preparedStatement.setLong(2, eventParam.getStartTime());
//            preparedStatement.setLong(3, eventParam.getEndTime());
//
//            ResultSet resultSet = preparedStatement.executeQuery();
//            if (resultSet.next()) {
//                int is_match = resultSet.getInt("is_match");
//                if (is_match <= eventParam.getThreshold()) {
//                    return false;
//                }
//            } else {
//                return false;
//            }
//
//        }
//        return true;
//
//    }

    @Override
    public void init(ParameterTool parameterTool) throws Exception {
        clickHouseConn = ConnectionUtils.getClickHouseConn(parameterTool);
    }

    @Override
    public String queryEventSequenceStr(LogBean bean, CombineCondition combineCondition) throws Exception {
        //在查询ClickHouse前，检查缓存是否可用？
        //TODO 查询缓存

        String sql = combineCondition.getSql();
        long startTime = combineCondition.getStartTime();
        long endTime = combineCondition.getEndTime();
        //获取规则中事先定义好的事件（关心的事件）
        List<String> targetEvents = combineCondition.getEventConditions().stream().map(EventCondition::getEventId).collect(Collectors.toList());

        PreparedStatement preparedStatement = clickHouseConn.prepareStatement(sql);
        preparedStatement.setString(1, bean.getDeviceId());
        preparedStatement.setLong(2, startTime);
        preparedStatement.setLong(3, endTime);
        ResultSet resultSet = preparedStatement.executeQuery();
        StringBuffer sb = new StringBuffer();
        if (resultSet.next()) {
            //将行为字符串映射成数字或字母
            String eventId = resultSet.getString(1);
            sb.append(targetEvents.indexOf(eventId) + 1);
        }
        return sb.toString();

    }
}
